home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / machack / Hacks95 / MagicTitleHack.sit / MagicTitle / MagicTitle Source&Stuff / Source / HackDragWindow.c < prev    next >
C/C++ Source or Header  |  1995-06-24  |  26KB  |  1,043 lines

  1. // HackDragWindow.c
  2.  
  3. #include "HackDragWindow.h"
  4. #include <Windows.h>
  5. #include <Menus.h>
  6. #include <TextUtils.h>
  7. #include <Files.h>
  8. #include <Traps.h>
  9. #include <A4Stuff.h>
  10. #include <SetupA4.h>
  11. #include <Resources.h>
  12. #include <ToolUtils.h>
  13. #include <Aliases.h>
  14.  
  15. #include "FinderAE.h"
  16. #include "FileSystemStuff.h"
  17.  
  18. #define waitingWindowsLimit 2
  19. #define waitingFilesLimit    10
  20.  
  21.  
  22. enum    {
  23.         fileIconID            = -4000,
  24.         folderIconID        = -3997,
  25.         hardDriveIconID        = -3995,
  26.         networkServerIconID    = -3972,
  27.         floppyIconID        = -3998,
  28.         cdRomIconID            = -3987
  29.         };
  30.  
  31. enum    {
  32.         iconMapValue        = 256,
  33.         fileIconTempID        = 260,
  34.         folderIconTempID,
  35.         hardDriveIconTempID
  36.         };
  37.         
  38. typedef struct WindowFileLink WindowFileLink;
  39. typedef WindowFileLink *WindowFileLinkPtr;
  40. typedef WindowFileLink **WindowFileLinkHandle;
  41.  
  42. typedef pascal void (* DragWindowProcPtr)        (WindowRef theWindow, Point startPt, const Rect *boundsRect);
  43. typedef pascal void (* CloseWindowProcPtr)        (WindowRef theWindow);
  44. typedef pascal void (* SetWTitleProcPtr)        (WindowRef theWindow, ConstStr255Param title);
  45. typedef pascal WindowRef (* NewWindowProcPtr)    (void *wStorage, const Rect *boundsRect, ConstStr255Param title, Boolean visible, short procID, WindowRef behind, Boolean goAwayFlag, long refCon);
  46. typedef pascal void (* ShowWindowProcPtr)        (WindowRef theWindow);
  47. typedef pascal short (* FindWindowProcPtr)        (Point thePoint, WindowRef *theWindow);
  48.  
  49. struct WindowFileLink
  50.     {
  51.     char    nameLength;
  52.     short    volume;
  53.     long    parID;
  54.     WindowPtr window;
  55.     };
  56.  
  57. typedef struct WindowFileLink WindowFileLink;
  58. typedef WindowFileLink *WindowFileLinkPtr;
  59. typedef WindowFileLink **WindowFileLinkHandle;
  60.  
  61. struct DocPathData
  62.     {
  63.     UniversalProcPtr        oldOpen;
  64.     UniversalProcPtr        oldClose;  // not used anymore
  65.     
  66.     UniversalProcPtr        oldDragWindow;
  67.     UniversalProcPtr        oldCloseWindow;
  68.     UniversalProcPtr        oldSetWTitle;
  69.     
  70.     UniversalProcPtr        oldOpenRF;
  71.     UniversalProcPtr        oldHFSDispatch;
  72.     
  73.     UniversalProcPtr        oldNewCWindow;
  74.     UniversalProcPtr        oldNewWindow;
  75.     UniversalProcPtr        oldShowWindow;
  76.     
  77.     UniversalProcPtr        oldFindWindow;
  78.     
  79.     char                    howManyWaitingFiles;
  80.     char                    howManyWaitingWindows;
  81.     FSSpec                    waitingFiles[waitingFilesLimit];
  82.     WindowPtr                waitingWindows[waitingWindowsLimit];
  83.     Str255                    waitingWindowTitles[waitingWindowsLimit];
  84.     WindowFileLinkHandle    links;
  85.     Boolean                    ignoringFiles;
  86.     };
  87.     
  88. typedef struct DocPathData DocPathData;
  89. typedef DocPathData *DocPathDataPtr;
  90. typedef DocPathData **DocPathDataHandle;
  91.      
  92. DocPathDataHandle data;
  93.  
  94. inline DocPathDataHandle HackData() { return data; }
  95. void DoHack(    DocPathDataHandle theData,
  96.                 const WindowPtr window,
  97.                 const FSSpec *file,
  98.                 short titleTop,
  99.                 short titleLeft,
  100.                 short titleRight);
  101.  
  102. Boolean RemoveHackWindow(DocPathDataHandle theData, WindowPtr window);
  103. void RememberDocWindow(    DocPathDataHandle theData, const WindowPtr window,
  104.                         const FSSpec *file, char position);
  105. Boolean FindDocFile(DocPathDataHandle theData, ConstStr255Param windowTitle,
  106.                     FSSpec *file, char *position);
  107. Boolean IsDocumentFile(    ConstStr255Param windowTitle, const FSSpec *file,
  108.                         char *position);
  109. void ConvertSpecToRefNum(DocPathDataHandle theData);
  110. Boolean CommandKey( void );
  111. Boolean OptionKey( void );
  112. void AppendItem(MenuHandle menuHandle, ConstStr255Param string, short type);
  113. void DoWindow(DocPathDataHandle theData, WindowPtr window, ConstStr255Param title);
  114. OSErr SetIconID( short oldID, short newID );
  115. void CompleteMenu(MenuHandle menuHandle);
  116. void MenuSelection(short selection, const FSSpec *file);
  117. long DoMenuSelect(MenuHandle menuHandle, Point position);
  118.  
  119. #pragma parameter __D1 GetD1()
  120. extern pascal long GetD1()
  121. ONEWORDINLINE(0x4e71);
  122.  
  123. pascal WindowPtr NewCWindowStub(void *wStorage,const Rect *boundsRect, ConstStr255Param title,
  124.                                 Boolean visible, short procID, WindowRef behind, Boolean goAwayFlag, long refCon);
  125. pascal WindowPtr NewWindowStub(void *wStorage,const Rect *boundsRect, ConstStr255Param title,
  126.                                 Boolean visible, short procID, WindowRef behind, Boolean goAwayFlag, long refCon);
  127.  
  128. pascal void ShowWindowStub(WindowRef window);
  129.  
  130. pascal short FindWindowStub(Point thePoint, WindowRef *theWindow);
  131.  
  132. void DoNewFile(DocPathDataHandle theData, const FSSpec *file );
  133. void PutFileOnWaitingList(DocPathDataHandle theData, const FSSpec *file);
  134. void PutWindowOnWaitingList(DocPathDataHandle theData, const WindowPtr window, ConstStr255Param title);
  135. Boolean RemoveWaitingWindow(DocPathDataHandle theData, const WindowPtr window);
  136. Boolean SameFile(const FSSpec *file1, const FSSpec *file2);
  137.  
  138. void OpenStub(void);
  139. void OpenRFStub(void);
  140. void HackOpen(HParmBlkPtr paramBlock);
  141.  
  142. void GetWindowTitleRect(WindowPtr window, Rect *titleRect);
  143. Boolean FindHackWindow(DocPathDataHandle theData, WindowPtr window, FSSpec *file);
  144.  
  145. void DragWindowStub();
  146. short HackDragWindow(WindowPtr, Point, Rect *);
  147.  
  148. void CloseWindowStub();
  149. void CloseWindowHack(WindowPtr window);
  150.  
  151. void SetWTitleStub();
  152. void SetWTitleHack(WindowPtr window, ConstStr255Param title);
  153.  
  154. void HFSDispatchStub(void);
  155. void HFSDispatchHack(long selector, HParmBlkPtr pb);
  156.  
  157.  
  158. inline void AppendFile(MenuHandle menuHandle, ConstStr255Param name)
  159.     {
  160.     AppendItem(menuHandle, name, fileIconTempID);
  161.     }
  162.  
  163. inline void AppendFolder(MenuHandle menuHandle, ConstStr255Param name)
  164.     {
  165.     AppendItem(menuHandle, name, folderIconTempID);
  166.     }
  167.  
  168. inline void AppendVolume(MenuHandle menuHandle, ConstStr255Param name)
  169.     {
  170.     AppendItem( menuHandle, name, hardDriveIconTempID);
  171.     }
  172.  
  173. void main(void)
  174. {
  175.     long oldA4;
  176.     Handle initH = 0;
  177.     
  178.     oldA4 = SetCurrentA4();
  179.     RememberA4();
  180.     
  181.     initH = Get1Resource('INIT', 333);
  182.     if(initH)
  183.         {
  184.         HackInit();
  185.         DetachResource(initH);
  186.         }
  187.         
  188.     RestoreA4(oldA4);
  189. }
  190.  
  191. void HackInit(void)
  192.     {  
  193.     data = (DocPathDataHandle) NewHandleSys(sizeof(DocPathData));
  194.     if(data)
  195.         {
  196.         (*data)->howManyWaitingFiles    =    0;
  197.         (*data)->howManyWaitingWindows    =    0;
  198.         (*data)->links        =    (WindowFileLinkHandle)    NewHandleSys(0);
  199.         (*data)->ignoringFiles = false;
  200.         
  201.         // (*data)->oldDragWindow = NGetTrapAddress (_DragWindow, ToolTrap);
  202.         // NSetTrapAddress ((UniversalProcPtr)DragWindowStub, _DragWindow, ToolTrap);        
  203.  
  204.         (*data)->oldCloseWindow = NGetTrapAddress (_CloseWindow, ToolTrap);
  205.         NSetTrapAddress ((UniversalProcPtr)CloseWindowStub, _CloseWindow, ToolTrap);
  206.                 
  207.         (*data)->oldSetWTitle = NGetTrapAddress (_SetWTitle, ToolTrap);
  208.         NSetTrapAddress ((UniversalProcPtr)SetWTitleStub, _SetWTitle, ToolTrap);        
  209.  
  210.         (*data)->oldOpen = NGetTrapAddress (_Open, OSTrap);
  211.         NSetTrapAddress ((UniversalProcPtr)OpenStub, _Open, OSTrap);
  212.                 
  213.         (*data)->oldOpenRF = NGetTrapAddress (_OpenRF, OSTrap);
  214.         NSetTrapAddress ((UniversalProcPtr)OpenRFStub, _OpenRF, OSTrap);
  215.                 
  216.         (*data)->oldHFSDispatch = NGetTrapAddress (_HFSDispatch, OSTrap);
  217.         NSetTrapAddress ((UniversalProcPtr)HFSDispatchStub, _HFSDispatch, OSTrap);    
  218.             
  219.         (*data)->oldNewCWindow = NGetTrapAddress (_NewCWindow, ToolTrap);
  220.         NSetTrapAddress ((UniversalProcPtr)NewCWindowStub, _NewCWindow, ToolTrap);    
  221.             
  222.         (*data)->oldNewWindow = NGetTrapAddress (_NewWindow, ToolTrap);
  223.         NSetTrapAddress ((UniversalProcPtr)NewWindowStub, _NewWindow, ToolTrap);
  224.                 
  225.         (*data)->oldFindWindow = NGetTrapAddress (_FindWindow, ToolTrap);
  226.         NSetTrapAddress ((UniversalProcPtr)FindWindowStub, _FindWindow, ToolTrap);
  227.                 
  228.         }
  229.     }
  230.  
  231.  
  232. asm void DragWindowStub( void )
  233.     {
  234.     
  235.     // Reserve space on the stack for real DragWindow address
  236.     sub.l    #4, SP
  237.     
  238.     // save registers
  239.     movem.l A0-A5/D0-D7, -(SP)
  240.     
  241.     jsr SetUpA4
  242.     
  243.     // save real DragWindow address on the stack
  244.     move.l data, A0
  245.     move.l (A0), A0    
  246.     move.l 8(A0), 56(SP)
  247.     
  248.     // move HackDragWindow params on the stack
  249.     move.l  64(SP),-(SP) 
  250.     move.l  72(SP),-(SP)
  251.     move.l  80(SP),-(SP)
  252.     
  253.     jsr HackDragWindow
  254.     
  255.     TST.W     D0
  256.     
  257.     // resotre stack pointer
  258.     LEA    12(SP),SP
  259.     movem.l (SP)+, A0-A5/D0-D7
  260.     
  261.     BNE.S     *+4
  262.     
  263.     // forget about calling real DragWindow
  264.     add.l      #4, SP    
  265.             
  266.     rts        
  267.     }
  268.  
  269. short HackDragWindow(WindowPtr window, Point startPoint, Rect *boundsRect)
  270.     {
  271.     Rect titleRect;
  272.     short titleStringLeft = 0, titleStringRight = 0;
  273.     Boolean doDrag = true;
  274.     DocPathDataHandle theData = HackData();
  275.     
  276.     GetWindowTitleRect(window, &titleRect);
  277.     
  278.     titleStringLeft =    (titleRect.left +
  279.                         titleRect.right - 
  280.                         ((WindowPeek) window)->titleWidth) / 2;
  281.     
  282.     titleStringRight =    (titleRect.left +
  283.                          titleRect.right + 
  284.                          ((WindowPeek) window)->titleWidth) / 2;
  285.                         
  286.     if(    CommandKey()                        && 
  287.         (startPoint.h > titleStringLeft)    &&
  288.         (startPoint.h < titleStringRight)    )
  289.         {
  290.         FSSpec file;
  291.         if(FindHackWindow(theData, window, &file))
  292.             {
  293.             doDrag = false;
  294.             DoHack(theData, window, &file, titleRect.top, titleStringLeft, titleStringRight);
  295.             }
  296.         }                
  297.     return     doDrag;
  298.     }
  299.  
  300. void DoHack(    DocPathDataHandle theData,
  301.                 const WindowPtr window,
  302.                 const FSSpec *file,
  303.                 short titleTop,
  304.                 short titleLeft,
  305.                 short titleRight)
  306.     {
  307.     MenuHandle menuHandle = NewMenu(55, "\p");
  308.     if(menuHandle)
  309.         {
  310.         CInfoPBRec pb;
  311.         Str255 curName;
  312.         OSErr error = noErr;
  313.         long selection;
  314.         Point position;
  315.         
  316.         short volume = file->vRefNum;
  317.         long directory = file->parID;
  318.         short done = 0;
  319.         
  320.         AppendFile(menuHandle,file->name);
  321.         pb.hFileInfo.ioCompletion = 0;
  322.         pb.hFileInfo.ioNamePtr = curName;
  323.         
  324.         do
  325.             {
  326.             pb.hFileInfo.ioFDirIndex = -1;
  327.             pb.hFileInfo.ioVRefNum = volume;
  328.             pb.hFileInfo.ioDirID = directory;
  329.  
  330.             error = PBGetCatInfoSync( &pb );
  331.             if(!error && (pb.hFileInfo.ioFlParID != directory))
  332.                 {
  333.                 directory = pb.hFileInfo.ioFlParID;
  334.                 AppendFolder(menuHandle, curName);                        
  335.                 }
  336.             else
  337.                 done = 1;
  338.             }
  339.         while(!done);
  340.         
  341.         CompleteMenu(menuHandle);
  342.         
  343.         InsertMenu(menuHandle, -1);
  344.         CalcMenuSize(menuHandle);
  345.     
  346.         position.v = titleTop;
  347.         position.h = (titleRight + titleLeft - (*menuHandle)->menuWidth)/2;
  348.         
  349.         selection = DoMenuSelect(menuHandle, position);
  350.         
  351.         if(HiWord(selection))
  352.             {
  353.             selection = LoWord(selection);
  354.             MenuSelection(selection, file);
  355.             }
  356.                     
  357.         DeleteMenu(55);
  358.         DisposeMenu(menuHandle);        
  359.         }
  360.     }
  361.  
  362. long DoMenuSelect(MenuHandle menuHandle, Point position)
  363.     {
  364.     short savedResFile = CurResFile();
  365.     long selection = 0;
  366.     
  367.     UseResFile(0);
  368.     SetIconID( folderIconID,        folderIconTempID );
  369.     SetIconID( fileIconID,            fileIconTempID );
  370.     SetIconID( hardDriveIconID,        hardDriveIconTempID );
  371.     
  372.     selection = PopUpMenuSelect( menuHandle, position.v, position.h, 0);
  373.     
  374.     SetIconID(folderIconTempID,        folderIconID );
  375.     SetIconID(fileIconTempID,        fileIconID );
  376.     SetIconID(hardDriveIconTempID,    hardDriveIconID );
  377.     UseResFile(savedResFile);
  378.     
  379.     return selection;
  380.     }
  381.     
  382. void MenuSelection(short selection, const FSSpec *file)
  383.     {
  384.     if(selection > 1)
  385.         {
  386.         Boolean bringFinderInFront = true;
  387.             {
  388.             FSSpec parent = *file, child;
  389.             OSErr err = noErr;
  390.             short count = 1;
  391.             for(; !err && (count < selection); count++)
  392.                 {
  393.                 child = parent;
  394.                 err = GetParent(&child, &parent);
  395.                 }
  396.             if(!err)
  397.                 {
  398.                 FinderOpen(&parent, bringFinderInFront);
  399.                 SelectItem(&child, bringFinderInFront);
  400.                 }
  401.             }
  402.         }    
  403.     }
  404.     
  405.     
  406. void AppendItem(MenuHandle menuHandle, ConstStr255Param string, short iconID)
  407.     {
  408.     short count = CountMItems(menuHandle) + 1;
  409.     AppendMenu(menuHandle, "\pa");
  410.     
  411.     SetMenuItemText(menuHandle, count, string);
  412.     
  413.     SetItemIcon(menuHandle, count, iconID - iconMapValue);
  414.     SetItemCmd(menuHandle, count, 0x1E);    
  415.     }
  416.  
  417. void CompleteMenu(MenuHandle menuHandle)
  418.     {
  419.     SetItemIcon(menuHandle, CountMItems(menuHandle), hardDriveIconTempID - iconMapValue);
  420.     }
  421.  
  422. OSErr SetIconID( short oldID, short newID )
  423.     {
  424.     Handle iconResource = nil;
  425.     
  426.     SetResLoad(false);
  427.     iconResource = GetResource('SICN', oldID);
  428.     SetResLoad(true);
  429.     if(iconResource)
  430.         {
  431.         Str255 name;
  432.         short id;
  433.         ResType type;
  434.         GetResInfo(iconResource, &id, &type, name);
  435.         if(!ResError())
  436.             SetResInfo(iconResource, newID, name);
  437.         
  438.         }        
  439.     return ResError();
  440.     }
  441.     
  442. void GetWindowTitleRect(WindowPtr window, Rect *titleRect)
  443.     {
  444.     *titleRect    = (**(((WindowPeek) window)->strucRgn)).rgnBBox;
  445.     titleRect->top++;
  446.     titleRect->bottom = (**(((WindowPeek) window)->contRgn)).rgnBBox.top - 1;
  447.     }
  448.     
  449.     
  450. void HackOpen(HParmBlkPtr pb)
  451.     {
  452.     if(!(GetD1() & 0x0400) && pb->fileParam.ioNamePtr)
  453.         {
  454.         FSSpec file;
  455.         OSErr err = MyFSMakeFSSpec (    pb->fileParam.ioVRefNum,
  456.                                         pb->fileParam.ioDirID,
  457.                                         pb->fileParam.ioNamePtr,
  458.                                         &file);
  459.         if(!err)
  460.             {
  461.             FInfo info;
  462.             Boolean alias = false;
  463.             
  464.             #define kIsAlias 0x8000
  465.             #define kHasBeenInited 0x100
  466.             err = FSpGetFInfo(&file, &info);
  467.             if(!err)
  468.                 {
  469.                 if (!(info.fdFlags & kIsAlias))
  470.                     {
  471.                     if((info.fdFlags & kHasBeenInited))
  472.                         DoNewFile(HackData(), &file);
  473.                     else
  474.                         {
  475.                         FSSpec parent;
  476.                         err = GetParent(&file, &parent);
  477.                         if(!err && !EqualString(parent.name, "\pRecent Documents", 0,0))
  478.                             DoNewFile(HackData(), &file);
  479.                         }
  480.                     
  481.                     }
  482.                 }
  483.             }
  484.         }    
  485.     }
  486.     
  487. void DoNewFile(DocPathDataHandle theData, const FSSpec *file )
  488.     {
  489.     WindowPtr window = 0;
  490.     char state = HGetState((Handle)theData);
  491.     DocPathDataPtr dataPtr = *theData;
  492.     short count;
  493.     char position;
  494.     HLock((Handle)theData);
  495.     
  496.     if(dataPtr->ignoringFiles)
  497.         {
  498.         if(!SameFile(file, &dataPtr->waitingFiles[0]))
  499.             dataPtr->ignoringFiles = false;
  500.         }
  501.  
  502.     if(!dataPtr->ignoringFiles)
  503.         {
  504.         for(count = dataPtr->howManyWaitingWindows - 1;(count >= 0) && !window; count--)
  505.             {
  506.             if(IsDocumentFile(dataPtr->waitingWindowTitles[count], file, &position))
  507.                 {
  508.                 window = dataPtr->waitingWindows[count];
  509.                 if(count < dataPtr->howManyWaitingWindows - 1)
  510.                     {
  511.                     BlockMoveData(    &(dataPtr->waitingWindows[count + 1]),
  512.                                     &(dataPtr->waitingWindows[count]),
  513.                                     (dataPtr->howManyWaitingWindows - 1 - count) * sizeof(WindowPtr));
  514.                                     
  515.                     BlockMoveData(    &(dataPtr->waitingWindowTitles[count + 1]),
  516.                                     &(dataPtr->waitingWindowTitles[count]),
  517.                                     (dataPtr->howManyWaitingWindows - 1 - count) * 256);
  518.                     }                
  519.                 dataPtr->howManyWaitingWindows--;
  520.                 dataPtr->ignoringFiles = true;
  521.                 dataPtr->waitingFiles[0] = *file;
  522.                 }
  523.             }
  524.         if(window)
  525.             RememberDocWindow(    theData, window, file, position);
  526.         else
  527.             PutFileOnWaitingList(theData, file);
  528.         }
  529.     HSetState((Handle) theData, state);
  530.     }
  531.  
  532. Boolean SameFile(const FSSpec *file1, const FSSpec *file2)
  533.     {
  534.     return     (file1->vRefNum    !=    file2->vRefNum    ) ? false :
  535.             (file1->parID    !=    file2->parID    ) ? false :
  536.             EqualString (file1->name, file2->name, 0, 0);
  537.     }
  538.     
  539. void PutFileOnWaitingList(DocPathDataHandle theData, const FSSpec *file)
  540.     {
  541.     if((*theData)->howManyWaitingFiles == waitingFilesLimit)
  542.         {
  543.         BlockMoveData(    &(*theData)->waitingFiles[1],
  544.                         &(*theData)->waitingFiles[0],
  545.                         (waitingFilesLimit - 1) * sizeof(FSSpec));
  546.         (*theData)->howManyWaitingFiles--;
  547.         }    
  548.     (*theData)->waitingFiles[(*theData)->howManyWaitingFiles++] = *file;
  549.     }
  550.     
  551. void PutWindowOnWaitingList(DocPathDataHandle theData, const WindowPtr window, ConstStr255Param title)
  552.     {
  553.     RemoveWaitingWindow(theData, window);
  554.     if((*theData)->howManyWaitingWindows == waitingWindowsLimit)
  555.         {
  556.         BlockMoveData(    &(*theData)->waitingWindows[1],
  557.                         &(*theData)->waitingWindows[0],
  558.                         (waitingWindowsLimit - 1) * sizeof(WindowPtr));
  559.                         
  560.         BlockMoveData(    &(*theData)->waitingWindowTitles[1],
  561.                         &(*theData)->waitingWindowTitles[0],
  562.                         (waitingWindowsLimit - 1) * 256);
  563.         (*theData)->howManyWaitingWindows--;
  564.         }
  565.     BlockMoveData(title, &(*theData)->waitingWindowTitles[(*theData)->howManyWaitingWindows], title[0] + 1);    
  566.     (*theData)->waitingWindows[(*theData)->howManyWaitingWindows++] = window;
  567.     }
  568.  
  569. asm void OpenStub( void )
  570.     {
  571.     
  572.     // Reserve space on the stack for real Open address
  573.     sub.l    #4, SP
  574.     
  575.     movem.l A1-A5/D0-D7, -(SP)
  576.     
  577.     move.l A0, -(SP)
  578.     
  579.     jsr SetUpA4
  580.     
  581.     move.l data, A0
  582.     move.l (A0), A0
  583.     
  584.     move.l (A0), 56(SP)
  585.     
  586.     jsr HackOpen
  587.     
  588.     move.l (SP)+,A0
  589.     
  590.     movem.l (SP)+, A1-A5/D0-D7
  591.     
  592.     rts    
  593.     }
  594.     
  595. asm void OpenRFStub( void )
  596.     {
  597.     
  598.     // Reserve space on the stack for real Open address
  599.     sub.l    #4, SP
  600.     
  601.     movem.l A1-A5/D0-D7, -(SP)
  602.     
  603.     move.l A0, -(SP)
  604.     
  605.     jsr SetUpA4
  606.     
  607.     move.l data, A0
  608.     move.l (A0), A0
  609.     
  610.     move.l 20(A0), 56(SP)
  611.     
  612.     jsr HackOpen
  613.     
  614.     move.l (SP)+,A0
  615.     
  616.     movem.l (SP)+, A1-A5/D0-D7
  617.     
  618.     rts    
  619.     }
  620.  
  621. asm void HFSDispatchStub( void )
  622.     {
  623.     
  624.     // Reserve space on the stack for real HFSDispatchStub address
  625.     sub.l    #4, SP
  626.     
  627.     movem.l A1-A5/D1-D7, -(SP)
  628.     
  629.     move.l A0, -(SP)
  630.     move.l D0, -(SP)
  631.     
  632.     jsr SetUpA4
  633.     
  634.     move.l data, A0
  635.     move.l (A0), A0
  636.     
  637.     move.l 24(A0), 56(SP)
  638.     
  639.     jsr HFSDispatchHack
  640.     
  641.     move.l (SP)+,D0
  642.     move.l (SP)+,A0
  643.     
  644.     movem.l (SP)+, A1-A5/D1-D7
  645.     
  646.     rts    
  647.     }
  648.  
  649. void HFSDispatchHack(long selector, HParmBlkPtr pb)
  650. {
  651.     if(selector == 0x1A)
  652.         HackOpen(pb);
  653. }
  654.  
  655. asm void SetWTitleStub()
  656. {
  657.     // Reserve space on the stack for real SetWTitle address
  658.     sub.l    #4, SP
  659.     
  660.     // save registers
  661.     movem.l A0-A5/D0-D7, -(SP)
  662.     
  663.     jsr SetUpA4
  664.     
  665.     move.l data, A0
  666.     move.l (A0), A0    
  667.     move.l 16(A0), 56(SP)
  668.     
  669.     // move SetWTitleHack params on the stack
  670.     move.l  64(SP),-(SP) 
  671.     move.l  72(SP),-(SP)
  672.     
  673.     jsr SetWTitleHack
  674.  
  675.     // resotre stack pointer
  676.     LEA    8(SP),SP
  677.     
  678.     // resotre registers
  679.     movem.l (SP)+, A0-A5/D0-D7
  680.     
  681.     rts    
  682. }
  683.  
  684. void SetWTitleHack(WindowPtr window, ConstStr255Param title)
  685.     {
  686.     DocPathDataHandle theData = HackData();
  687.     DoWindow(theData, window, title);
  688.     }
  689.  
  690. void DoWindow(DocPathDataHandle theData, WindowPtr window, ConstStr255Param title)
  691.     {
  692.     RemoveHackWindow(theData, window);
  693.     RemoveWaitingWindow(theData, window);
  694.     if(theData)
  695.         {
  696.         FSSpec file;
  697.         char position;
  698.         Boolean found = FindDocFile(theData,title, &file, &position);
  699.         (*theData)->ignoringFiles = false;
  700.         
  701.         if(found)
  702.             RememberDocWindow(theData, window, &file, position);
  703.         else
  704.             PutWindowOnWaitingList(theData, window, title);
  705.         }
  706.     }
  707.  
  708. Boolean FindDocFile(DocPathDataHandle theData, ConstStr255Param windowTitle,
  709.                     FSSpec *file, char *position)
  710.     {
  711.     Boolean found = false;
  712.     if(theData)
  713.         {
  714.         char state = HGetState((Handle)theData);
  715.         DocPathDataPtr dataPtr = *theData;
  716.         short count;
  717.         HLock((Handle)theData);
  718.         
  719.         for(count = dataPtr->howManyWaitingFiles - 1;(count >= 0) && !found; count--)
  720.             {
  721.             if(IsDocumentFile(windowTitle, &dataPtr->waitingFiles[count], position))
  722.                 {
  723.                 found = true;
  724.                 *file = dataPtr->waitingFiles[count];
  725.                 if(count < dataPtr->howManyWaitingFiles - 1)
  726.                     BlockMoveData(    &(dataPtr->waitingFiles[count + 1]),
  727.                                     &(dataPtr->waitingFiles[count]),
  728.                                     (dataPtr->howManyWaitingFiles - 1 - count) * sizeof(FSSpec));
  729.                 dataPtr->howManyWaitingFiles--;
  730.                 }
  731.             }
  732.         HSetState((Handle) theData, state);
  733.         }
  734.     return found;
  735.     }
  736.  
  737. inline Boolean IsDelimiter(unsigned char c)
  738.     {
  739.     return    ((c >= '0' && c <= '9')        || 
  740.              (c >= 'A' && c <= 'Z')        ||
  741.              (c >= 'a' && c <= 'z'))    ||
  742.              (c==' ')                    ?
  743.              false : true;
  744.     }
  745.         
  746. Boolean IsDocumentFile(    ConstStr255Param windowTitle, const FSSpec *file, char *position)
  747.     {
  748.     unsigned char fnameLen = file->name[0];
  749.     Boolean result = false;
  750.     if(windowTitle[0] == fnameLen)
  751.         {
  752.         *position = 0;
  753.         return EqualString (windowTitle, file->name, 0, 0);
  754.         }
  755.      else if((windowTitle[0] < fnameLen))
  756.          return 0;
  757.      else
  758.          {
  759.          unsigned char tempChar;
  760.         unsigned char *midPtr;
  761.          if(IsDelimiter(windowTitle[fnameLen + 1]))
  762.              {
  763.              *position = 1;
  764.              tempChar = windowTitle[0];
  765.              *((unsigned char *) windowTitle) = fnameLen;
  766.              result = EqualString (windowTitle, file->name, 0, 0);
  767.              *((unsigned char *) windowTitle) = tempChar;
  768.              if(result)
  769.                  return 1;
  770.              }             
  771.         
  772.         midPtr = (StringPtr)windowTitle + windowTitle[0] - fnameLen;
  773.         tempChar = *midPtr;
  774.         if(IsDelimiter(tempChar))
  775.             {
  776.             *position = -1;
  777.             *midPtr = fnameLen;        
  778.             result = EqualString (midPtr, file->name, 0, 0);
  779.             *midPtr = tempChar;
  780.             }
  781.         }
  782.     return result;
  783.     }         
  784.     
  785. void RememberDocWindow(    DocPathDataHandle theData, const WindowPtr window,
  786.                         const FSSpec *file, char position)
  787.     {
  788.     if(theData)
  789.         {
  790.         WindowFileLinkHandle LData = (*theData)->links;
  791.         (*theData)->howManyWaitingFiles = 0;
  792.         if(LData)
  793.             {
  794.             Size size = GetHandleSize((Handle) LData);
  795.             char state = HGetState((Handle) LData);
  796.             HUnlock((Handle) LData);
  797.             SetHandleSize ((Handle) LData, size + sizeof(WindowFileLink));
  798.             if(!MemError())
  799.                 {
  800.                 WindowFileLinkPtr dataPtr = *LData + size/sizeof(WindowFileLink);
  801.                 HLock((Handle) LData);
  802.                 dataPtr->window        = window;
  803.                 dataPtr->volume        = file->vRefNum;
  804.                 dataPtr->parID        = file->parID;
  805.                 dataPtr->nameLength = position * file->name[0];
  806.                 }
  807.             HSetState((Handle) LData, state);
  808.             }    
  809.         }
  810.     }
  811.  
  812. Boolean FindHackWindow(DocPathDataHandle theData, WindowPtr window, FSSpec *file)
  813.     {
  814.     Boolean found = false;
  815.     if(theData)
  816.         {
  817.         WindowFileLinkHandle LData = (*theData)->links;
  818.         if(LData)
  819.             {
  820.             char state = HGetState((Handle) LData);
  821.             Size size = GetHandleSize((Handle) LData);
  822.             WindowFileLinkPtr dataPtr = *LData;
  823.             WindowFileLinkPtr endPtr = dataPtr + size/sizeof(WindowFileLink);
  824.             
  825.             HLock((Handle) LData);
  826.             for(; dataPtr < endPtr && !found; dataPtr++)
  827.                 {
  828.                 if(dataPtr->window  == window)
  829.                     {
  830.                     Str255 windowTitle;
  831.                     found = true;
  832.                     file->vRefNum = dataPtr->volume;
  833.                     file->parID = dataPtr->parID;
  834.                     GetWTitle(window, windowTitle);
  835.                     if(dataPtr->nameLength == 0)
  836.                         BlockMoveData(windowTitle, file->name, windowTitle[0] + 1);
  837.                     else if(dataPtr->nameLength > 0)
  838.                         {
  839.                         file->name[0] = dataPtr->nameLength;
  840.                         BlockMoveData(windowTitle + 1, file->name + 1,  dataPtr->nameLength);
  841.                         }
  842.                     else
  843.                         {
  844.                         file->name[0] = -dataPtr->nameLength;
  845.                         BlockMoveData(    windowTitle + 1 + windowTitle[0] + dataPtr->nameLength,
  846.                                         file->name + 1,  -dataPtr->nameLength);
  847.                         }
  848.                     }
  849.                 }
  850.             HSetState((Handle) LData, state);
  851.             }
  852.         }
  853.     return found;
  854.     }
  855.     
  856.     
  857. Boolean RemoveHackWindow(DocPathDataHandle theData, WindowPtr window)
  858.     {
  859.     Boolean found = false;
  860.     if(theData)
  861.         {
  862.         WindowFileLinkHandle LData = (*theData)->links;
  863.         if(LData)
  864.             {
  865.             char state = HGetState((Handle) LData);
  866.             Size size = GetHandleSize((Handle) LData);
  867.             WindowFileLinkPtr dataPtr = *LData;
  868.             WindowFileLinkPtr endPtr = dataPtr + size/sizeof(WindowFileLink);
  869.             
  870.             HLock((Handle) LData);
  871.             for(; dataPtr < endPtr && !found; dataPtr++)
  872.                 {
  873.                 if(dataPtr->window  == window)
  874.                     {
  875.                     found = true;
  876.                     if((dataPtr + 1) < endPtr)
  877.                         {
  878.                         Ptr sourcePtr = (Ptr) (dataPtr + 1);
  879.                         long howMany = (Ptr) endPtr - sourcePtr;
  880.                         BlockMoveData(sourcePtr, dataPtr, howMany);
  881.                         }
  882.                     }
  883.                 }
  884.             HSetState((Handle) LData, state);            
  885.             if(found)
  886.                 SetHandleSize((Handle) LData, size - sizeof(WindowFileLink));
  887.             }
  888.         }
  889.     return found;
  890.     }
  891.  
  892. asm void CloseWindowStub()
  893. {
  894.     // Reserve space on the stack for real CloseWindow address
  895.     sub.l    #4, SP
  896.     
  897.     // save registers
  898.     movem.l A0-A5/D0-D7, -(SP)
  899.     
  900.     jsr SetUpA4
  901.     
  902.     // save real CloseWindow address on the stack
  903.     move.l data, A0
  904.     move.l (A0), A0    
  905.     move.l 12(A0), 56(SP)
  906.     
  907.     // move CloseWindow param on the stack
  908.     move.l  64(SP),-(SP) 
  909.     
  910.     jsr CloseWindowHack
  911.  
  912.     // resotre stack pointer
  913.     LEA    4(SP),SP
  914.     
  915.     // resotre registers
  916.     movem.l (SP)+, A0-A5/D0-D7
  917.     
  918.     rts    
  919. }
  920.  
  921. void CloseWindowHack(WindowPtr window)
  922. {
  923.     DocPathDataHandle theData = HackData();
  924.     (*theData)->howManyWaitingFiles = 0;
  925.     if(!RemoveWaitingWindow(theData, window))
  926.         RemoveHackWindow(theData, window);
  927. }
  928.  
  929.  
  930. Boolean RemoveWaitingWindow(DocPathDataHandle theData, const WindowPtr window)
  931.     {
  932.     Boolean found = false;
  933.     if(theData)
  934.         {
  935.         char state = HGetState((Handle)theData);
  936.         DocPathDataPtr dataPtr = *theData;
  937.         short count;
  938.         HLock((Handle)theData);
  939.         
  940.         for(count = dataPtr->howManyWaitingWindows - 1;(count >= 0) && !found; count--)
  941.             {
  942.             if(window == dataPtr->waitingWindows[count])
  943.                 {
  944.                 found = true;
  945.                 if(count < dataPtr->howManyWaitingWindows - 1)
  946.                     {
  947.                     BlockMoveData(    &(dataPtr->waitingWindows[count + 1]),
  948.                                     &(dataPtr->waitingWindows[count]),
  949.                                     (dataPtr->howManyWaitingWindows - 1 - count) * sizeof(WindowPtr));
  950.                                     
  951.                     BlockMoveData(    &(dataPtr->waitingWindowTitles[count + 1]),
  952.                                     &(dataPtr->waitingWindowTitles[count]),
  953.                                     (dataPtr->howManyWaitingWindows - 1 - count) * 256);
  954.                     }
  955.                 dataPtr->howManyWaitingWindows--;
  956.                 }
  957.             }
  958.         HSetState((Handle) theData, state);
  959.         }
  960.     return found;
  961.     }
  962.     
  963. Boolean CommandKey( void )
  964. {
  965.     KeyMap keys;
  966.     
  967.     GetKeys(keys);
  968.     return (keys[1] & ( 1L << 15)) ? true : false;
  969. }
  970.  
  971. Boolean OptionKey( void )
  972. {
  973.     KeyMap keys;
  974.     
  975.     GetKeys(keys);
  976.     return (keys[1] & ( 1L << 2)) ? true : false;
  977. }
  978.  
  979. // evil, evil...
  980. pascal WindowPtr NewCWindowStub(void *wStorage, const Rect *boundsRect,
  981.                                 ConstStr255Param title,Boolean visible,
  982.                                 short procID, WindowRef behind,
  983.                                 Boolean goAwayFlag, long refCon)
  984. {
  985.     long oldA4 = SetUpA4();
  986.     DocPathDataHandle theData = HackData();
  987.     
  988.     WindowPtr window = ((NewWindowProcPtr)((*data)->oldNewCWindow))
  989.                                  (wStorage,boundsRect,
  990.                                 title,visible,
  991.                                 procID, behind,
  992.                                 goAwayFlag, refCon);
  993.     if(window)
  994.         DoWindow(theData, window, title);
  995.     
  996.     RestoreA4(oldA4);
  997.     return window;
  998. }
  999.  
  1000. pascal WindowRef NewWindowStub(    void *wStorage, const Rect *boundsRect,
  1001.                                 ConstStr255Param title, Boolean visible,
  1002.                                 short theProc, WindowRef behind,
  1003.                                 Boolean goAwayFlag, long refCon)
  1004. {
  1005.     long oldA4 = SetUpA4();
  1006.     DocPathDataHandle theData = HackData();
  1007.     
  1008.     WindowPtr window = ((NewWindowProcPtr)((*data)->oldNewWindow))
  1009.                                  (wStorage,boundsRect,
  1010.                                 title,visible,
  1011.                                 theProc, behind,
  1012.                                 goAwayFlag, refCon);
  1013.     if(window)
  1014.         DoWindow(theData, window, title);
  1015.     
  1016.     RestoreA4(oldA4);
  1017.     return window;
  1018. }
  1019.  
  1020. pascal short FindWindowStub( Point p, WindowRef *window)
  1021. {
  1022.     long oldA4 = SetUpA4();
  1023.     DocPathDataHandle theData = HackData();
  1024.     Boolean didIt = false;
  1025.     
  1026.     short code = ((FindWindowProcPtr)((*data)->oldFindWindow))
  1027.                                  (p,window);
  1028.     if(window && (code == inDrag))
  1029.         {
  1030.         Rect boundsRect;
  1031.         didIt = !HackDragWindow(*window, p, &boundsRect);
  1032.         }
  1033.         
  1034.     if(didIt)
  1035.         {
  1036.         *window = 0;
  1037.         code = inDesk;
  1038.         }
  1039.         
  1040.     RestoreA4(oldA4);
  1041.     return code;
  1042. }
  1043.